// ---------------------------------------------------------------------
//
// -- 游戏场景中介层
// -- author £
//
// ---------------------------------------------------------------------

const HexagonUtil = require('HexagonUtil'),
    CommonInfo = require('CommonInfo'),
    SaveData = require('SaveData'),
    Platform = require('Platform'),
    Alert = require('Alert'),
    AppInfo = require('AppInfo'),
    CommonUtil = require('CommonUtil'),
    superClass = require('game_single_base').GameSingleMediator;

const MAX_REVIVE_TIME = 1,
    MAX_REFRESH_TIME = 1,
    START_LASER_COUNT = 1,
    START_BOMB_COUNT = 1,
    START_HAMMER_COUNT = 1,

    GET_REFRESH_COUNT = 0,
    GET_LASER_COUNT = 1,
    GET_BOMB_COUNT = 1,
    GET_HAMMER_COUNT = 1,

    TOTAL_REFRESH_COUNT = 3,
    REVIVE_TIME = 30,
    UPLOAD_TIME_INIT = 2,
    UPLOAD_TIME_ADD = 0,
    UPLOAD_MAX_TIME = 180,
    CLOSE_SUB_TIME = 20,

    SCORE_PER_PROGRESS = 1000,
    MAX_SCORE = 100000,

    AD_ALERT_TIME = 8,
    REVIVE_AD_ERROR_STR = '视频播放如遇问题，点击确定进行复活。(请升级最新版本微信！)',
    REFRESH_AD_ERROR_STR = '视频播放如遇问题，点击确定使用换一批。(请升级最新版本微信！)',
    RCOIN_FAIL_STR = '对不起，复活币使用失败。',
    RCOIN_NOT_ENOUGH_STR = '对不起，您的复活币不足',

    LASER_STRING = '激光',
    BOMB_STRING = '炸弹',
    HAMMER_STRING = '锤子',
    REFRESH_STRING = '换一批';

let cl = cc.Class({
    extends: superClass,
    properties: {
    },

    initCtor: function () {
        CommonUtil.mysuper(superClass, this, 'initCtor');
        this.model = require('HexagonModel');
        this._instructOnce = false;
        this._adTime = 0;
        this._coinRevive = true;
    },

    clearData: function () {
        CommonUtil.mysuper(superClass, this, 'clearData');
        this._reviveCount = 0;
        this._refreshCount = 3;
        this._curScore = 0;
        this._curUploadTime = UPLOAD_TIME_INIT;
        this._canUpdateScore = false;
        this._laserCount = 1;
        this._bombCount = 0;
        this._hammerCount = 1;
        this._getLaserCount = GET_LASER_COUNT;
        this._getHammerCount = GET_HAMMER_COUNT;
        this._getBombCount = GET_BOMB_COUNT;
        this._getRefreshCount = GET_REFRESH_COUNT;
    },

    onRegister: function (v) {
        CommonUtil.mysuper(superClass, this, 'onRegister', v);


    },

    onShow: function () {
        CommonUtil.mysuper(superClass, this, 'onShow');

        if (SaveData.data) {
            this.model.recover(SaveData.data);
            this.recover(SaveData.data);
        } else {
            this.StartGameS();
            this.scene.updateRefreshTime(this._refreshCount, this._getRefreshCount, TOTAL_REFRESH_COUNT);
            this.scene.laserEnable(this._laserCount, this._getLaserCount);
            this.scene.hammerEnable(this._hammerCount, this._getHammerCount);
            this.scene.bombEnable(this._bombCount, this._getBombCount);

            if (this._instructOnce) return;

            this._instructOnce = true;
            this.scene.playInstruction();
        }

        if (!CommonInfo.getTeched()) {
            this.scene.showTechPanel();
        }

        this.updateSurpassScore();
    },

    updateSurpassScore: function () {
        if (!AppInfo.isIOS) {
            let startScore = Math.floor(this._curScore / SCORE_PER_PROGRESS) * SCORE_PER_PROGRESS,
                percent = Math.ceil(this._curScore / MAX_SCORE * 100);

            if (percent >= 100) percent = 99;

            this.scene.updateSurpassScore(
                startScore, startScore + SCORE_PER_PROGRESS,
                percent
            );
        }
    },

    recover: function (data) {
        this._instructOnce = true;

        if (data.score)
            this._curScore = data.score;

        if (data.refreshCount !== undefined && data.refreshCount !== null)
            this._refreshCount = data.refreshCount;
        if (data.laserCount !== undefined && data.laserCount !== null)
            this._laserCount = data.laserCount;
        if (data.hammerCount !== undefined && data.hammerCount !== null)
            this._hammerCount = data.hammerCount;
        if (data.bombCount !== undefined && data.bombCount !== null)
            this._bombCount = data.bombCount;

        if (data.getRefreshCount !== undefined && data.getRefreshCount !== null)
            this._getRefreshCount = data.getRefreshCount;
        if (data.getLaserCount !== undefined && data.getLaserCount !== null)
            this._getLaserCount = data.getLaserCount;
        if (data.getHammerCount !== undefined && data.getHammerCount !== null)
            this._getHammerCount = data.getHammerCount;
        if (data.getBombCount !== undefined && data.getBombCount !== null)
            this._getBombCount = data.bombCount;

        if (data.reviveCount === undefined || data.reviveCount === null)
            this._reviveCount = MAX_REVIVE_TIME;
        else
            this._reviveCount = data.reviveCount;

        console.log('reviveCount:', this._reviveCount);
        this.scene.recover(data);
        this.scene.laserEnable(this._laserCount, this._getLaserCount);
        this.scene.hammerEnable(this._hammerCount, this._getHammerCount);
        this.scene.bombEnable(this._bombCount, this._getBombCount);
        this.scene.updateRefreshTime(this._refreshCount, this._getRefreshCount, TOTAL_REFRESH_COUNT);
        this.scene.refreshItems(this.model._items);
        this.scene.setItemEnable(this.model.checkItems());
        // this._scheduler.schedule(this._uploadScore, UPLOAD_TIME_INIT, 1, 0, this, 'upload');
        this._scheduler.schedule(this._uploadScore, UPLOAD_TIME_INIT,
            1, 0, this, 'upload');

        Platform.postMessage({
            message: 'recover',
            score: this._curScore
        });
    },

    onRelease: function () {
        CommonUtil.mysuper(superClass, this, 'onRelease');
    },

    resetData: function () {
        CommonUtil.mysuper(superClass, this, 'resetData');
        this._scheduler.unscheduleAllCallbacks();
        this._curUploadTime = UPLOAD_TIME_INIT;
        this._canUpdateScore = false;
    },

    createNewItem: function () {
        let checkResults = null;

        this.model.createNewItem();
        this.scene.createNewItem(this.model.selectIndex,
            this.model.selectData());
        checkResults = this.model.checkItems();
        this.scene.setItemEnable(checkResults);

        if (!checkResults[0] && !checkResults[1] && !checkResults[2]) {
            Platform.postMessage({
                message: 'history_best',
                score: this._curScore
            });
            CommonInfo.setCurScore(this._curScore);
            require('GameConfig').userProto.saveScore();
            this.scene.showEndTip();
            SaveData.clear();
            this._scheduler.unschedule('upload');

            if (this._reviveCount === MAX_REVIVE_TIME) {
                CommonInfo.showResult = true;
                CommonUtil.delay(
                    this.scene.node, 2,
                    function () {
                        this.skipReviveHandler();
                    }, this
                );
                // this._showLobbyResult();
            } else {
                CommonUtil.delay(
                    this.scene.node, 2,
                    function () {
                        // if (CommonInfo.getAutoRevive()) {
                        //     this.reviveHandler();
                        //     return;
                        // }

                        Platform.postMessage({
                            message: 'hide'
                        });
                        Platform.postMessage({
                            message: 'to_revive',
                            score: this._curScore
                        });
                        this._coinRevive = !this._coinRevive;

                        if (this._coinRevive && !CommonInfo.getRCoinNum()) {
                            this._coinRevive = false;
                        }

                        if (AppInfo.adBanned)
                            this._coinRevive = true;

                        this.scene.showRevive(this._coinRevive);
                    }, this
                );

                // this._scheduler.schedule(this._cdHandler, 1, cc.macro.REPEAT_FOREVER, 0, this, 'revive');
            }
        }
    },

    getLaser: function () {
        this._laserCount += START_LASER_COUNT;
        --this._getLaserCount;
        this.scene.laserEnable(this._laserCount, this._getLaserCount);
        this.scene.hideGetItem();
        this._setSaveData();
    },

    getRefresh: function () {
        this._refreshCount += MAX_REFRESH_TIME;
        --this._getRefreshCount;
        this.scene.updateRefreshTime(this._refreshCount, this._getRefreshCount);
        this.scene.hideGetItem();
        this._setSaveData();
    },

    getHammer: function () {
        this._hammerCount += START_HAMMER_COUNT;
        --this._getHammerCount;
        this.scene.hammerEnable(this._hammerCount, this._getHammerCount);
        this.scene.hideGetItem();
        this._setSaveData();
    },

    getBomb: function () {
        this._bombCount += START_BOMB_COUNT;
        --this._getBombCount;
        this.scene.bombEnable(this._bombCount, this._getBombCount);
        this.scene.hideGetItem();
        this._setSaveData();
    },

    revive: function () {
        console.log('reviveeeeeeeeeeeeeeeeeeeeeeeeeeee');
        ++this._reviveCount;
        this.model.revive();
        this.scene.revive();
        this._setSaveData();
        this._uploadScore();
    },

    getItem: function () {
        switch (this._curGetItem) {
            case 'laser':
                this.getLaser();
                break;
            case 'refresh':
                this.getRefresh();
                break;
            case 'hammer':
                this.getHammer();
                break;
            case 'bomb':
                this.getBomb();
                break;
        }
    },

    useItem: function () {
        switch (this._curGetItem) {
            case 'laser':
                break;
            case 'refresh':
                this.useRefresh();
                break;
            case 'hammer':
                break;
            case 'bomb':
                break;
        }
    },

    _setSaveData: function () {
        if (!this._curScore) return;

        SaveData.save({
            score: this._curScore,
            reviveCount: this._reviveCount,
            refreshCount: this._refreshCount,
            items: this.model._items,
            grids: this.model._grids,
            laserCount: this._laserCount,
            bombCount: this._bombCount,
            hammerCount: this._hammerCount,
            getLaserCount: this._getLaserCount,
            getBombCount: this._getBombCount,
            getHammerCount: this._getHammerCount,
            getRefreshCount: this._getRefreshCount
        });
    },

    _updateScore: function (ds, firstIndex) {
        this.scene.updateScore(this._curScore);
        this.scene.showFloatScore(ds, firstIndex);
        this.updateSurpassScore();
        this._setSaveData();

        /*if (this._canUpdateScore) {
            this._canUpdateScore = false;
            Platform.postMessage({
                message: 'update_score',
                score: this._curScore
            });
            this.scene.startDrawSub();
            this._scheduler.schedule(this._uploadScore, this._curUploadTime, 1, 0, this, 'upload');
            this._scheduler.schedule(this._stopSubDraw, CLOSE_SUB_TIME, 1, 0, this, 'draw');
        }*/
        this._uploadScore();
    },

    _useSkillCommon: function () {
        let checkResults;

        checkResults = this.model.checkItems();
        this.scene.setItemEnable(checkResults);
        this._setSaveData();
    },

    //------------------------------------------------------------------------------

    changeRCoinFinish: function (xhrData) {
        this.inLoadData(false, 'server');

        if (xhrData.code) {
            this.changeRCoinFail(null, xhrData.code === 10310);
            return;
        }

        console.log('changeRCoinFinish1');
        CommonInfo.updateRCoinNum(-1);
        this.revive();
    },

    changeRCoinFail: function (status, notEnough) {
        this.inLoadData(false, 'server');
        Alert.show(null,
            notEnough ? RCOIN_NOT_ENOUGH_STR : RCOIN_FAIL_STR, null,
            this.skipReviveHandler, this
        );
    },

    //------------------------------------------------------------------------------

    StartGameS: function () {
        this.roundReset();
        this.model.StartGameS();
        this.scene.StartGameS({
            items: this.model._items
        });

        // this._scheduler.schedule(this._uploadScore, UPLOAD_TIME_INIT, 1, 0, this, 'upload');
        this._scheduler.schedule(this._uploadScore, UPLOAD_TIME_INIT,
            1, 0, this, 'upload');

    },

    //------------------------------------------------------------------------------

    _uploadScore: function () {
        /*if (!AppInfo.wx) return;

        console.log('uploadScore');
        this._scheduler.unschedule('upload');
        this._curUploadTime += UPLOAD_TIME_ADD;
        this._canUpdateScore = true;

        if (this._curUploadTime > UPLOAD_MAX_TIME)
            this._curUploadTime = UPLOAD_MAX_TIME;*/


        if (!AppInfo.isIOS) return;

        this._scheduler.unschedule('upload');
        Platform.postMessage({
            message: 'update_score',
            score: this._curScore
        });

    },

    _stopSubDraw: function () {
        console.log('_stopSubDraw');
        this.scene.stop();
        this._scheduler.unschedule('draw');
    },

    _cdHandler: function () {
        if (this._scheduler.deltaTime('revive') < REVIVE_TIME) return;

        this._scheduler.unschedule('revive');
        this.toLobbyScene();
    },

    hammerHandler: function (index) {
        if (this.model.isGridFree(index)) return;

        this.model.useHammer(index);
        --this._hammerCount;
        this.scene.useHammer(index, this.model.getGridColor(index));
        this.scene.hammerEnable(this._hammerCount, this._getHammerCount);
        this._useSkillCommon();
    },

    bombHandler: function (index) {
        let erases = this.model.useBomb(index);

        --this._bombCount;
        this.scene.useBomb(index, erases);
        this.scene.bombEnable(this._bombCount, this._getBombCount);
        this._useSkillCommon();
    },

    clickHammerHandler: function () {
        if (this._hammerCount <= 0 && this._getHammerCount > 0) {
            this.scene.showGetItem(HAMMER_STRING, START_HAMMER_COUNT);
            this._curGetItem = 'hammer';
        }
    },

    clickBombHandler: function () {
        console.log('clickBombHandler');
        if (this._bombCount <= 0 && this._getBombCount > 0) {
            this.scene.showGetItem(BOMB_STRING, START_BOMB_COUNT);
            this._curGetItem = 'bomb';
        }
    },

    laserHandler: function () {
        if (this._laserCount <= 0 && this._getLaserCount > 0) {
            this.scene.showGetItem(LASER_STRING, START_LASER_COUNT);
            this._curGetItem = 'laser';
            return;
        }

        let data = HexagonUtil.createLasers(),
            erases = this.model.useLaser(data);
        console.log('erases', erases);
        --this._laserCount;
        this.scene.useLaser(data, erases);
        this.scene.laserEnable(this._laserCount, this._getLaserCount);
        this._useSkillCommon();
    },

    refreshHandler: function () {
        /*if (this._refreshCount <= 0 && this._getRefreshCount > 0) {
            this.scene.showGetItem(REFRESH_STRING, MAX_REFRESH_TIME);
            this._curGetItem = 'refresh';
            return;
        }

        let checkResults;

        --this._refreshCount;
        this.model.refreshItems(true);
        this.scene.refreshItems(this.model._items);
        this.scene.updateRefreshTime(this._refreshCount, this._getRefreshCount, TOTAL_REFRESH_COUNT);
        checkResults = this.model.checkItems();
        this.scene.setItemEnable(checkResults);
        this._setSaveData();*/

        this._curGetItem = 'refresh';

        if (!AppInfo.adBanned) {
            this.getItemHandler();
        } else {
            this._adTime = 15;
            this.adItemCloseHandler();
        }
    },

    useRefresh: function () {
        let checkResults;

        --this._refreshCount;
        this.model.refreshItems(true);
        this.scene.refreshItems(this.model._items);
        this.scene.updateRefreshTime(this._refreshCount, this._getRefreshCount, TOTAL_REFRESH_COUNT);
        checkResults = this.model.checkItems();
        this.scene.setItemEnable(checkResults);
        this._setSaveData();
    },

    getItemHandler: function () {
        this.inLoadData(true, 'ad');
        this._scheduler.schedule(this._adItemCheckHandler, 1, cc.macro.REPEAT_FOREVER, 0, this, 'ad');
        Platform.showVideoAd(
            (this.adItemCloseHandler).bind(this),
            (this.adItemErrorHandler).bind(this),
        );
        // Platform.hideBannerAd();
        // this.getItem();
    },

    skipReviveHandler: function () {
        // this._showLobbyResult();
        this._scheduler.unschedule('revive');
        this._scheduler.unschedule('ad');
        this.inLoadData(false, 'ad');
        CommonInfo.showResult = true;
        SaveData.clear();

        if (AppInfo.wx) {
            // Platform.hideBannerAd();
            Platform.scaleSharedCanvas();
            console.log('history_best:', this._curScore);
            Platform.postMessage({
                message: 'history_best',
                score: this._curScore
            });
            Platform.postMessage({
                message: 'hide'
            });
            Platform.postMessage({
                message: 'to_result',
                score: this._curScore
            });
        }

        this.toLobbyScene();
    },

    reviveOldHandler: function () {
        this.skipReviveHandler();
        // this.revive();
    },

    reviveHandler: function () {
        this.inLoadData(true, 'ad');
        this._scheduler.unschedule('revive');
        this._scheduler.schedule(this._adCheckHandler, 1, cc.macro.REPEAT_FOREVER, 0, this, 'ad');
        this.scene.autoRevive();
        Platform.showVideoAd(
            (this.adCloseHandler).bind(this),
            (this.adErrorHandler).bind(this),
        );
        // Platform.hideBannerAd();
    },

    _adCheckHandler: function () {
        ++this._adTime;

        if (this._adTime === AD_ALERT_TIME) {
            this.scene.showVideoAlert(
                REVIVE_AD_ERROR_STR,
                function () {
                    this._adTime = 15;
                    this.adCloseHandler();
                }, this
            )
        }
    },

    adErrorHandler: function (e) {
        console.log('adErrorHandler:', e);
        this.inLoadData(false, 'ad');
        this._scheduler.unschedule('ad');
        Platform.hideVideoAd();
        // Platform.showBannerAd();
        this.skipReviveHandler();
        this._adTime = 0;
    },

    adCloseHandler: function () {
        this.inLoadData(false, 'ad');

        if (!CommonInfo.getAutoRevive())
            CommonInfo.setAutoRevive(this.scene.getReviveData());

        this._scheduler.unschedule('ad');
        // Platform.showBannerAd();

        if (this._adTime < 14) {
            this.skipReviveHandler();
            return;
        }

        this._adTime = 0;
        this.revive();
        // Platform.hideBannerAd();
        // Platform.hideVideoAd();
    },

    _adItemCheckHandler: function () {
        ++this._adTime;

        if (this._adTime === AD_ALERT_TIME) {
            this.scene.showVideoAlert(
                REFRESH_AD_ERROR_STR,
                function () {
                    this._adTime = 15;
                    this.adItemCloseHandler();
                }, this
            )
        }
    },

    adItemErrorHandler: function (e) {
        console.log('adItemErrorHandler:', e);
        this.inLoadData(false, 'ad');
        this._scheduler.unschedule('ad');
        Platform.hideVideoAd();
        // Platform.showBannerAd();
        this.scene.hideGetItem();
        this._adTime = 0;
    },

    /*adItemCloseHandler: function () {
        this.inLoadData(false, 'ad');
        this._scheduler.unschedule('ad');
        Platform.showBannerAd();

        if (this._adTime < 14) {
            this.scene.hideGetItem();
            return;
        }

        this._adTime = 0;
        this.getItem();
        // Platform.hideBannerAd();
        // Platform.hideVideoAd();
    },*/

    adItemCloseHandler: function () {
        this.inLoadData(false, 'ad');
        this._scheduler.unschedule('ad');
        this.scene.hideVideoAlert();
        // Platform.showBannerAd();

        if (this._adTime < 14) {
            // this.scene.hideGetItem();
            return;
        }

        this._adTime = 0;
        this.useItem();
    },

    selectItemHandler: function (index) {
        this.model.selectIndex = index;
    },

    moveHandler: function (index) {
        this.model.curIndexes = null;

        if (index >= 0) {
            this.model.curIndexes = this.model.checkGrid(index);
        }

        this.scene.showHL(this.model.curIndexes);
    },

    moveEndHandler: function () {
        if (!this.model.curIndexes) return;

        let erases, ds, firstIndex = this.model.curIndexes[0];

        this.scene.showGrids(this.model.curIndexes,
            this.model.getSelectColor());
        this.model.setGrids();
        erases = this.model.getEraseIndexes();

        if (erases) {
            ds = HexagonUtil.getEraseScore(erases);
            this._curScore += ds;
            this.scene.eraseGrids(erases);
            this._updateScore(ds, firstIndex);
        } else {
            ds = HexagonUtil.BASE_SCORE;
            this._curScore += ds;
            this._updateScore(ds, firstIndex);
        }

        this.createNewItem();
    },

    returnHandler: function (e) {
        if (CommonInfo.sceneState === 0) return;

        CommonInfo.showResult = false;
        this.toLobbyScene();

        if (e)
            e.stopPropagationImmediate();

        SaveData.clear();
    },

    techHideHandler: function () {
        CommonInfo.setTeched(true);
    },

    useCoinReviveHandler: function () {
        this.inLoadData(true, 'server');
        require('GameConfig').userProto.changeItem(
            CommonInfo.rCoinId, -1,
            (this.changeRCoinFinish).bind(this),
            (this.changeRCoinFail).bind(this)
        );
    },

});

let HexagonMediator = new cl();

module.exports = HexagonMediator;
